/**
 * Created with IntelliJ IDEA.
 * User: Jeremy Schulte
 * Date: 11/15/13
 * Time: 7:15 PM
 */
///API imports.
import org.apache.derby.iapi.services.io.FileUtil;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.MaskFormatter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*This class is only for GUI creation!  Please create separate inner and outer classes for further functions, such as Listeners.
 * Coded by Jeremy Schulte*/

@SuppressWarnings("serial")
public class PracticeGUI extends JFrame {

    // Will be used to set minimum window sizes.
    private final int WINDOW_WIDTH = 839;
    private final int WINDOW_HEIGHT = 586;

    Format formatter;
    MaskFormatter mask1;

    // Panels.
    private JPanel titlePanel;
    private JPanel centerPanel;
    private JPanel westPanel;
    private JPanel southPanel;
    private JPanel buttonPanel;
    private JPanel statusPanel;

    // Labels.
    private JLabel titleLabel;
    private JLabel dateLabel;
    static JLabel formsLabel;
    static JLabel stepsLabel;
    static JLabel knowledgeLabel;
    static JLabel otherLabel;
    static JLabel formsTime;
    static JLabel stepsTime;
    static JLabel knowledgeTime;
    static JLabel otherTime;
    static JLabel statusLabel;

    // TextFields.
    static JFormattedTextField dateField;

    // Buttons.
    private JButton saveButton;
    private JButton quitButton;
    private JButton clearButton;
    private JButton historyButton;
    private JButton formsButton;
    private JButton stepsButton;
    private JButton knowledgeButton;
    private JButton otherButton;
    private JButton getDateButton;

    // Table.
    static DefaultTableModel tableModel;

    // JTable
    static JTable resultsTable;

    // Menu elements.
    private JMenuBar jMenuBar1;
    private JMenu jFile;
    private JMenuItem jExitItem;
    private JMenuItem jCreateItem;
    private JMenuItem jResetItem;
    private JMenu jFHelp;
    private JMenuItem jAboutItem;
    private JMenuItem jHelpItem;
    private JMenu jOptions;
    private JMenuItem jCustomizeItem;
    private JMenuItem jPrintItem;

    // Time related fields.
    private Long formsTime1;
    private Long formsTime2;
    private Long formsTimeDiff;

    private Long stepsTime1;
    private Long stepsTime2;
    private Long stepsTimeDiff;

    private Long knowledgeTime1;
    private Long knowledgeTime2;
    private Long knowledgeTimeDiff;

    private Long otherTime1;
    private Long otherTime2;
    private Long otherTimeDiff;

    // Scroll pane for the JTable.
    private JScrollPane scroller;

    // Initial table setup.
    private String[] columns = { "Date", PracticeControl.setForms,
            PracticeControl.setSteps, PracticeControl.setKnowledge,
            PracticeControl.setOther };
    private String[][] data = null;

    static String returnDate;

    // For debug purposes.
    private static boolean DEBUG = false;

    PracticeControl pC = new PracticeControl();

    // Coded by Jeremy Schulte
    public PracticeGUI() {
        super("Martial Arts Practice Tracker");

        // Minimum size.
        setMinimumSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT));

        // Frame image.
        BufferedImage image = null;
        try {
            image = ImageIO.read(getClass().getResource("/Images/icon.png"));
        } catch (IOException e) {
            if (DEBUG)
                e.printStackTrace();
        }
        setIconImage(image);

        // Build menu.
        buildMenu();

        // Build JFrame and JComponents.
        buildPanel();

        // Add the components to the JFrame.
        add(titlePanel, BorderLayout.NORTH);
        add(westPanel, BorderLayout.WEST);
        add(centerPanel, BorderLayout.CENTER);
        add(southPanel, BorderLayout.SOUTH);

    }

    private void buildMenu() {

        jMenuBar1 = new JMenuBar();

        jFile = new JMenu("File");
        jFile.setMnemonic(KeyEvent.VK_F);
        jCreateItem = new JMenuItem("Create database");
        jCreateItem.addActionListener(new ButtonListener());
        jCreateItem.setMnemonic(KeyEvent.VK_C);
        jCreateItem.setToolTipText("Creates database to save data.");
        jFile.add(jCreateItem);

        jPrintItem = new JMenuItem("Print Table");
        jPrintItem.setToolTipText("Sends table to the printer");
        jPrintItem.setMnemonic(KeyEvent.VK_P);
        jPrintItem.addActionListener(new ButtonListener());
        jFile.add(jPrintItem);

        jExitItem = new JMenuItem("Exit");
        jExitItem.setMnemonic(KeyEvent.VK_E);
        jExitItem.setToolTipText("Click to exit");
        jExitItem.addActionListener(new ButtonListener());
        jFile.add(jExitItem);

        jOptions = new JMenu("Options");
        jOptions.setMnemonic(KeyEvent.VK_O);
        jCustomizeItem = new JMenuItem("Customize Labels");
        jOptions.add(jCustomizeItem);
        jCustomizeItem.setMnemonic(KeyEvent.VK_C);
        jCustomizeItem.setToolTipText("Customize timer labels.");
        jCustomizeItem.addActionListener(new ButtonListener());
        jResetItem = new JMenuItem("Reset Program");
        jResetItem.addActionListener(new ButtonListener());
        jResetItem.setMnemonic(KeyEvent.VK_R);
        jResetItem.setToolTipText("Reset program defaults.");
        jOptions.add(jResetItem);

        jFHelp = new JMenu("Help");
        jFHelp.setMnemonic(KeyEvent.VK_H);
        jAboutItem = new JMenuItem();
        jAboutItem.setText("About this program");
        jAboutItem.setToolTipText("About this program.");
        jAboutItem.setMnemonic(KeyEvent.VK_A);
        jAboutItem.addActionListener(new ButtonListener());
        jFHelp.add(jAboutItem);
        jHelpItem = new JMenuItem("Instructions");
        jHelpItem.setToolTipText("Instructions for program.");
        jHelpItem.setMnemonic(KeyEvent.VK_I);
        jHelpItem.addActionListener(new ButtonListener());
        jFHelp.add(jHelpItem);

        jMenuBar1.add(jFile);
        jMenuBar1.add(jOptions);
        jMenuBar1.add(jFHelp);

        setJMenuBar(jMenuBar1);

    }

    // Coded by Jeremy Schulte
    private void buildPanel() {
        GridBagConstraints gbc = new GridBagConstraints();

        // Title panel.
        titlePanel = new JPanel();

        // Border.
        titlePanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));

        BufferedImage titleImg = null;
        try {
            titleImg = ImageIO
                    .read(getClass().getResource("/Images/title.png"));
        } catch (IOException e) {
            if (DEBUG)
                e.printStackTrace();
        }
        titleLabel = new JLabel(new ImageIcon(titleImg));

        titlePanel.setLayout(new FlowLayout());
        titlePanel.add(titleLabel);

        // West Panel.
        westPanel = new JPanel();

        // Border.
        westPanel.setBorder(BorderFactory.createTitledBorder(""));

        dateLabel = new JLabel("Date: ");
        dateLabel.setFont(new Font("Arial", Font.TRUETYPE_FONT, 18));

        try {
            mask1 = new MaskFormatter("##/##/##");
            dateField = new JFormattedTextField(mask1);
            dateField.setFont(new Font("Arial", Font.BOLD, 16));
        } catch (ParseException e) {
            if (DEBUG)
                e.printStackTrace();
        }

        getDateButton = new JButton("Today");
        getDateButton.addActionListener(new ButtonListener());

        formsLabel = new JLabel(PracticeControl.setForms);
        formsLabel.setFont(new Font("Arial", Font.TRUETYPE_FONT, 18));
        formsButton = new JButton("Start");
        formsButton.addActionListener(new ButtonListener());
        formsTime = new JLabel("");
        formsTime.setFont(new Font("Arial", Font.BOLD, 14));
        formsTime.setForeground(Color.RED);

        stepsLabel = new JLabel(PracticeControl.setSteps);
        stepsLabel.setFont(new Font("Arial", Font.TRUETYPE_FONT, 18));
        stepsButton = new JButton("Start");
        stepsTime = new JLabel("");
        stepsTime.setFont(new Font("Arial", Font.BOLD, 14));
        stepsTime.setForeground(Color.RED);
        stepsButton.addActionListener(new ButtonListener());

        knowledgeLabel = new JLabel(PracticeControl.setKnowledge);
        knowledgeLabel.setFont(new Font("Arial", Font.TRUETYPE_FONT, 18));
        knowledgeButton = new JButton("Start");
        knowledgeTime = new JLabel("");
        knowledgeTime.setFont(new Font("Arial", Font.BOLD, 14));
        knowledgeTime.setForeground(Color.RED);
        knowledgeButton.addActionListener(new ButtonListener());

        otherLabel = new JLabel(PracticeControl.setOther);
        otherLabel.setFont(new Font("Arial", Font.TRUETYPE_FONT, 18));

        otherButton = new JButton("Start");
        otherTime = new JLabel("");
        otherTime.setFont(new Font("Arial", Font.BOLD, 14));
        otherTime.setForeground(Color.RED);
        otherButton.addActionListener(new ButtonListener());

        westPanel.setLayout(new GridBagLayout());

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.ipadx = 0;
        gbc.ipady = 15;
        gbc.weighty = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(dateLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.ipadx = 60;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(dateField, gbc);

        gbc.gridx = 2;
        gbc.gridy = 0;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(getDateButton, gbc);

        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        westPanel.add(formsLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(formsButton, gbc);

        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(formsTime, gbc);

        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        westPanel.add(stepsLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(stepsButton, gbc);

        gbc.gridx = 2;
        gbc.gridy = 3;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(stepsTime, gbc);

        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        westPanel.add(knowledgeLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 4;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(knowledgeButton, gbc);

        gbc.gridx = 2;
        gbc.gridy = 4;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(knowledgeTime, gbc);

        gbc.gridx = 0;
        gbc.gridy = 5;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        westPanel.add(otherLabel, gbc);

        gbc.gridx = 1;
        gbc.gridy = 5;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(otherButton, gbc);

        gbc.gridx = 2;
        gbc.gridy = 5;
        gbc.ipadx = 0;
        gbc.ipady = 0;
        gbc.weighty = 15;
        gbc.weightx = 0;
        gbc.anchor = GridBagConstraints.WEST;
        westPanel.add(otherTime, gbc);

        // Center Panel.
        centerPanel = new JPanel();

        // Border.
        centerPanel.setBorder(BorderFactory.createTitledBorder(""));

        tableModel = new DefaultTableModel(data, columns);

        centerPanel.setLayout(new FlowLayout());
        resultsTable = new JTable(tableModel);
        resultsTable.setFont(new Font("Arial", Font.TRUETYPE_FONT, 12));
        scroller = new JScrollPane(resultsTable);

        // Layout
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.ipadx = 0;
        gbc.ipady = 0;

        scroller.setVisible(true);
        centerPanel.add(scroller);

        // South Panel.
        southPanel = new JPanel();

        // Border.
        southPanel.setBorder(BorderFactory.createEtchedBorder());

        historyButton = new JButton("History");
        historyButton.addActionListener(new ButtonListener());
        historyButton.setMnemonic(KeyEvent.VK_V);
        saveButton = new JButton("Save");
        saveButton.addActionListener(new ButtonListener());
        saveButton.setMnemonic(KeyEvent.VK_S);
        quitButton = new JButton("Quit");
        quitButton.addActionListener(new ButtonListener());
        quitButton.setMnemonic(KeyEvent.VK_Q);
        clearButton = new JButton("Clear");
        clearButton.addActionListener(new ButtonListener());
        clearButton.setMnemonic(KeyEvent.VK_C);

        southPanel.setLayout(new BorderLayout());

        // This is a subpanel of the south panel is for buttons.
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());
        buttonPanel.add(quitButton);
        buttonPanel.add(clearButton);
        buttonPanel.add(saveButton);
        buttonPanel.add(historyButton);

        // This is a subpanel of the south panel to act as a pseudo status bar.
        statusPanel = new JPanel();
        statusPanel.setLayout(new GridLayout(1, 1));

        // Border.
        statusPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));

        // statusbar items.
        statusLabel = new JLabel("");
        statusLabel.setFont(new Font("Arial", Font.BOLD, 9));
        statusLabel.setVisible(true);
        statusPanel.add(statusLabel);

        southPanel.add(buttonPanel, BorderLayout.NORTH);
        southPanel.add(statusPanel, BorderLayout.SOUTH);

    }

    public class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            statusLabel.setText("");
            if (e.getSource() == formsButton) {
                String text = formsButton.getText();
                if (text == "Start") {
                    formsTime.setText("");
                    formsButton.setText("Stop");
                    formsTime1 = System.currentTimeMillis();

                }

                else if (text == "Stop") {
                    formsTime.setText("");
                    formsButton.setText("Start");
                    formsTime2 = System.currentTimeMillis();
                    formsTimeDiff = formsTime2 - formsTime1;
                    formsTimeDiff = formsTimeDiff / 1000 / 60;
                    formsTime.setText(formsTimeDiff + " minutes");

                }
            }

            if (e.getSource() == stepsButton) {
                String text = stepsButton.getText();
                if (text == "Start") {
                    stepsTime.setText("");
                    stepsButton.setText("Stop");
                    stepsTime1 = System.currentTimeMillis();

                }

                else if (text == "Stop") {
                    stepsTime.setText("");
                    stepsButton.setText("Start");
                    stepsTime2 = System.currentTimeMillis();
                    stepsTimeDiff = stepsTime2 - stepsTime1;
                    stepsTimeDiff = stepsTimeDiff / 1000 / 60;
                    stepsTime.setText(stepsTimeDiff + " minutes");

                }
            }

            if (e.getSource() == knowledgeButton) {
                String text = knowledgeButton.getText();
                if (text == "Start") {
                    knowledgeTime.setText("");
                    knowledgeButton.setText("Stop");
                    knowledgeTime1 = System.currentTimeMillis();

                }

                else if (text == "Stop") {
                    knowledgeTime.setText("");
                    knowledgeButton.setText("Start");
                    knowledgeTime2 = System.currentTimeMillis();
                    knowledgeTimeDiff = knowledgeTime2 - knowledgeTime1;
                    knowledgeTimeDiff = knowledgeTimeDiff / 1000 / 60;
                    knowledgeTime.setText(knowledgeTimeDiff + " minutes");

                }

            }

            if (e.getSource() == otherButton) {
                String text = otherButton.getText();
                if (text == "Start") {
                    otherTime.setText("");
                    otherButton.setText("Stop");
                    otherTime1 = System.currentTimeMillis();

                }

                else if (text == "Stop") {
                    otherTime.setText("");
                    otherButton.setText("Start");
                    otherTime2 = System.currentTimeMillis();
                    otherTimeDiff = otherTime2 - otherTime1;
                    otherTimeDiff = otherTimeDiff / 1000 / 60;
                    otherTime.setText(otherTimeDiff + " minutes");

                }
            }

            if (e.getSource() == getDateButton) {
                formatter = new SimpleDateFormat("MM/dd/yy");
                String date = formatter.format(new Date());
                dateField.setValue(date);

            }

            if (e.getSource() == saveButton) {
                returnDate = dateField.getText();
                if (DEBUG) {
                    System.out.println(returnDate);
                    System.out.println(formsTime.getText());
                    System.out.println(stepsTime.getText());
                    System.out.println(knowledgeTime.getText());
                    System.out.println(otherTime.getText());
                }

                pC.dbWrite();

            }

            if (e.getSource() == historyButton) {
                tableModel.setDataVector(null, columns);
                pC.dbRead();
            }

            if (e.getSource() == jCreateItem) {
                JOptionPane.showMessageDialog(null, "This will take a bit.");
                pC.dbCreate();

            }
            if (e.getSource() == quitButton || e.getSource() == jExitItem) {
                System.exit(0);
            }
            if (e.getSource() == jResetItem) {
                int warning = JOptionPane.showConfirmDialog(null,
                        "This will delete all data and preferences.",
                        "Warning", JOptionPane.OK_CANCEL_OPTION);
                if (warning == JOptionPane.YES_OPTION) {
                    formsTime.setText("");
                    formsLabel.setText("Forms");
                    stepsTime.setText("");
                    stepsLabel.setText("One-Steps");
                    knowledgeTime.setText("");
                    knowledgeLabel.setText("Knowledge");
                    otherLabel.setText("Other");
                    otherTime.setText("");
                    dateField.setText("");
                    formsButton.setText("Start");
                    stepsButton.setText("Start");
                    knowledgeButton.setText("Start");
                    otherButton.setText("Start");
                    tableModel.setDataVector(null, columns);
                    statusLabel.setText("Reset.");
                    resultsTable.getColumnModel().getColumn(1)
                            .setHeaderValue("Forms");
                    resultsTable.getColumnModel().getColumn(2)
                            .setHeaderValue("One-Steps");
                    resultsTable.getColumnModel().getColumn(3)
                            .setHeaderValue("Knowledge");
                    resultsTable.getColumnModel().getColumn(4)
                            .setHeaderValue("Other");
                    PracticeControl.prefsFile.delete();
                    statusLabel.setText("Defaults set.");
                    FileUtil.removeDirectory(new File("practiceDB"));

                } else {
                    statusLabel.setText("Canceled.");
                }

            }

            if (e.getSource() == clearButton) {
                formsTime.setText("");
                stepsTime.setText("");
                knowledgeTime.setText("");
                otherTime.setText("");
                dateField.setText("");
                formsButton.setText("Start");
                stepsButton.setText("Start");
                knowledgeButton.setText("Start");
                otherButton.setText("Start");
                tableModel.setDataVector(null, columns);
                statusLabel.setText("Reset.");
                otherLabel.setText(PracticeControl.setOther);
                resultsTable.getColumnModel().getColumn(4)
                        .setHeaderValue(PracticeControl.setOther);
                tableModel.setDataVector(null, columns);
                statusLabel.setText("Cleared.");

            }

            if (e.getSource() == jCustomizeItem) {
                CustomizeGUI cGUI = new CustomizeGUI();
                cGUI.setVisible(true);
            }

            if (e.getSource() == jAboutItem) {
                JOptionPane
                        .showMessageDialog(null,
                                "  Practice Tracker 1.0\n Built by: Jeremy Schulte\n        \u00a9 2012");
            }

            if (e.getSource() == jHelpItem) {
                JOptionPane
                        .showMessageDialog(
                                null,
                                "The first step is to create a database from the file menu.  This will take up to 20 seconds. \n"
                                        + "From here, everything is pretty straightforward.  The date can be entered, or you can press the Today button to get the current date.\n"
                                        + "Each Lable for the timed tasks can be customized via the Options menu.\n  Each label must be set at the same time, or the unset labels"
                                        + "will revert back to their default state.\n"
                                        + "To time a task, click the start button.  Each task is measued in minutes.  Click stop when finished. \n"
                                        + "Do this for each task until you are finished for your session.  Click save to store the results in the database.\n"
                                        + "Click History will pull up all database results.  Clicking Clear, resets the timers and table view.\n"
                                        + "If you experience any problems with the application, choose Reset from the Options menu.",
                                "Instructions", JOptionPane.INFORMATION_MESSAGE);
            }

            if (e.getSource() == jPrintItem) {
                pC.dbRead();
                pC.dbPrint();
            }

        }

    }

}
